#Qbrush show
import sys, math
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QPoint, QPointF
from PyQt5.QtGui import (QColor,QPen, QPainter, QPainterPath, QPolygonF, QBrush, 
                         QLinearGradient, QConicalGradient, QRadialGradient, QGradient,
                         QPixmap)
from PyQt5.QtWidgets import (QApplication, QWidget, QHBoxLayout, QFormLayout, 
                             QLabel, QFrame, QSizePolicy, QSpinBox, QPushButton,
                             QColorDialog, QComboBox, QFileDialog)
 
class MyFrame(QFrame):
    def __init__(self, parent = None):
        super(MyFrame, self).__init__(parent)
        self.setFrameShape(QFrame.Box)
        self.setFrameShadow(QFrame.Plain)
        self.setLineWidth(1)
        self.setMidLineWidth(0)
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        
        self.brushColor = Qt.black
        self.pattern = Qt.SolidPattern
        self.filename = ''
        
    def setBrushColor(self, color):
        self.brushColor = color
        self.update()
        
    def setPattern(self, pattern):
        self.pattern = pattern
        self.update()
                
    def setTexture(self, filename):
        self.pattern = Qt.TexturePattern
        self.filename = filename
        self.update()
        
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing, True)
        
        #绘制边框线
        painter.drawRect(self.rect())
        
        pen = QPen()
        pen.setColor(Qt.darkBlue)
        painter.setPen(pen)
        
        brush = QBrush()
        brush.setColor(self.brushColor)
        
        if self.pattern == Qt.TexturePattern:
            brush.setTexture(QPixmap(self.filename))
        elif self.pattern == Qt.LinearGradientPattern:
            lg = QLinearGradient(0, 0, 100, 0)
            lg.setColorAt(0, Qt.red)
            #lg.setSpread(QGradient.RepeatSpread)
            lg.setColorAt(1, Qt.blue)
            brush = QBrush(lg)          
        elif self.pattern == Qt.RadialGradientPattern:
            rg = QRadialGradient(50, 50, 200, 100, 100)
            rg.setColorAt(0, Qt.red)
            rg.setColorAt(1, Qt.blue)
            rg.setSpread(QGradient.RepeatSpread)
            brush = QBrush(rg)  
        elif self.pattern == Qt.ConicalGradientPattern:
            cg = QConicalGradient(100, 100, 120)
            cg.setColorAt(0, Qt.red)
            cg.setColorAt(1, Qt.blue)
            cg.setSpread(QGradient.RepeatSpread)
            brush = QBrush(cg)
        else:
            brush.setStyle(self.pattern)
 
        painter.setBrush(brush)   
        painter.drawRect(10, 10, 200, 160)
        painter.drawEllipse(300, 10, 160, 160)      
        painter.drawPie(10, 240, 240, 240, 30 * 16, 110 * 16)
        
        #绘制五角星
        #添加一个多边形(五角星)
        #外点：x=Rcos(72°*k)  y=Rsin(72°*k)   k=0,1,2,3,4
        #内点：r=Rsin18°/sin36°  x=rcos(72°*k+36°)  y=rsin(72°*k+36°)   k=0,1,2,3,4
        deg_18 = 18 * math.pi / 180
        deg_36 = 36 * math.pi / 180
        deg_72 = 72 * math.pi / 180
        r_out = 100 #半径
        r_inner = r_out * math.sin(deg_18) / math.sin(deg_36)
        polygon = QPolygonF()
        for i in range (5) :   
            #外点
            out_angle = deg_72 * i - deg_18   
            polygon.append(QPointF(r_out * math.cos(out_angle), r_out * math.sin(out_angle))) 
            #内点
            in_angle =  deg_72 * i + deg_18
            polygon.append(QPointF(r_inner * math.cos(in_angle), r_inner * math.sin(in_angle)))
        
        painter.translate(380, 280)
        painter.drawPolygon(polygon, Qt.WindingFill)
        
        
class DemoBrush(QWidget):
    def __init__(self, parent=None):
        super(DemoBrush, self).__init__(parent)   
        
        # 设置窗口标题
        self.setWindowTitle('实战PyQt5: QBrush演示') 
        
        #设置尺寸
        self.resize(720, 400)    
              
        self.initUi()
        
    def initUi(self):
        layout = QHBoxLayout()
        
        self.canvas = MyFrame()
        
        #颜色设置
        btnSetColor = QPushButton('设置颜色')
        btnSetColor.clicked.connect(self.onSetBrushColor)
        
        #填充模式
        cmbBrusStyle = QComboBox()
        cmbBrusStyle.addItems(['NoBrush', 'SolidPattern', 'Dense1Pattern', 'Dense2Pattern', 
                               'Dense3Pattern', 'Dense4Pattern','Dense5Pattern','Dense6Pattern',
                               'Dense7Pattern', 'HorPattern', 'VerPattern', 'CrossPattern',
                               'BDiagPattern', 'FDiagPattern', 'DiagCrossPattern'])
        cmbBrusStyle.currentTextChanged.connect(self.onBrushStyleChanged)
        cmbBrusStyle.setCurrentIndex(1)
        
        #渐变
        cmbGradient = QComboBox()
        cmbGradient.addItems(['None', 'LinearGradientPattern', 'RadialGradientPattern', 'ConicalGradientPattern'])
        cmbGradient.currentTextChanged.connect(self.onGradientChanged)
        
        #纹理
        btnTexture = QPushButton('打开图像文件')
        btnTexture.clicked.connect(self.onButtonTextureClicked)
        
        fLayout = QFormLayout()
        fLayout.setContentsMargins(0,0,0,0)
        fLayout.addRow('颜色: ', btnSetColor)
        fLayout.addRow('填充模式: ', cmbBrusStyle)
        fLayout.addRow('渐变: ', cmbGradient)
        fLayout.addRow('纹理: ', btnTexture)
        
        wid_left = QWidget()
        wid_left.setMaximumWidth(200)
        wid_left.setLayout(fLayout)
                  
        layout.addWidget(wid_left)
        layout.addWidget(self.canvas)
        
        self.setLayout(layout)
        
    def onSetBrushColor(self):
       color = QColorDialog.getColor()
       self.canvas.setBrushColor(color)
       
    def onBrushStyleChanged(self, style):
        if style == 'SolidPattern':
            self.canvas.setPattern(Qt.SolidPattern)
        elif style == 'Dense1Pattern':
            self.canvas.setPattern(Qt.Dense1Pattern)
        elif style == 'Dense2Pattern':
            self.canvas.setPattern(Qt.Dense2Pattern)
        elif style == 'Dense3Pattern':
            self.canvas.setPattern(Qt.Dense3Pattern)
        elif style == 'Dense4Pattern':
            self.canvas.setPattern(Qt.Dense4Pattern)
        elif style == 'Dense5Pattern':
            self.canvas.setPattern(Qt.Dense5Pattern)
        elif style == 'Dense6Pattern':
            self.canvas.setPattern(Qt.Dense6Pattern)
        elif style == 'Dense7Pattern':
            self.canvas.setPattern(Qt.Dense7Pattern)
        elif style == 'HorPattern':
            self.canvas.setPattern(Qt.HorPattern)
        elif style == 'VerPattern':
            self.canvas.setPattern(Qt.VerPattern)
        elif style == 'CrossPattern':
            self.canvas.setPattern(Qt.CrossPattern)
        elif style == 'BDiagPattern':
            self.canvas.setPattern(Qt.BDiagPattern)
        elif style == 'FDiagPattern':
            self.canvas.setPattern(Qt.FDiagPattern)
        elif style == 'DiagCrossPattern':
            self.canvas.setPattern(Qt.DiagCrossPattern)
        else:
            self.canvas.setPattern(Qt.NoBrush)
            
    def onGradientChanged(self, style):
        if style == 'LinearGradientPattern':
            self.canvas.setPattern(Qt.LinearGradientPattern)
        elif style == 'RadialGradientPattern':
            self.canvas.setPattern(Qt.RadialGradientPattern)
        elif style == 'ConicalGradientPattern':
            self.canvas.setPattern(Qt.ConicalGradientPattern)
        else:
            self.canvas.setPattern(Qt.NoBrush)
            
    def onButtonTextureClicked(self):
        path,_ = QFileDialog.getOpenFileName(self, '打开图像文件', '', '图像文件 (*.png)')
        
        if path:
            self.canvas.setTexture(path)
            
    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = DemoBrush()
    window.show()
    sys.exit(app.exec())